package com.wjf.accesscontrol.util.sdkUtils;

import static com.wjf.accesscontrol.util.ConstantKt.READ_ERR_CARD_NULL;
import static com.wjf.accesscontrol.util.ConstantKt.READ_ERR_NO_CONNECT;
import static com.wjf.accesscontrol.util.ConstantKt.READ_ERR_PSAM_NULL;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbDevice;
import android.os.Environment;
import com.ivsign.android.IDCReader.IDCReaderSDK;
import com.mingtech.sscarddirver.Reader;
import com.wjf.accesscontrol.entity.IdCardEntity;
import com.wjf.accesscontrol.entity.SocialCardEntity;
import com.wjf.accesscontrol.util.AnysizeIDCMsg;
import com.wjf.accesscontrol.util.LogUtils;
import com.wjf.accesscontrol.util.ToastUtils;
import com.wjf.accesscontrol.util.ToolFun;
import com.wjf.accesscontrol.util.UsbDevPermission;

import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * @Description
 * @Author WuJianFeng
 * @Date 2024/1/26 11:32
 */

public class ReadCardUtils {

    private static ReadCardUtils instance;
    public static ReadCardUtils getInstance(){
        if (instance == null){
            synchronized (ReadCardUtils.class){
                if (instance == null){
                    instance = new ReadCardUtils();
                }
            }
        }
        return instance;
    }

    private UsbDevPermission usbPermission;
    private List<UsbDevDesc> mUsbDescList = new ArrayList<UsbDevDesc>();

    private Context context;
    private ReadCallback readCallback;

    /**
     * 1：接触卡
     * 2：非接卡
     * 3：自动寻卡，接触卡优先
     * 4：自动寻卡，非接触卡优先
     */
    private int iType = 1;

    public void init(Context context){
        this.context = context;
        usbPermission = new UsbDevPermission(context);

    }

    public void setReadCallback(ReadCallback readCallback){
        this.readCallback = readCallback;
    }

    public void clearCallback(){
        readCallback = null;
    }

    private ReadCardUtils(){}

    public void deviceConnect() {
        long st = 0;
        int deviceFd = 0;
        mUsbDescList.clear();
        HashMap<String, UsbDevice> usbDeviceHashMap = usbPermission.GetDeviceList();
        if (usbDeviceHashMap != null && usbDeviceHashMap.size() > 0) {
            if (!usbDeviceHashMap.isEmpty()) {
                for (UsbDevice device : usbDeviceHashMap.values()) {
                    if ((0x10C4 == device.getVendorId()) || (0x23A4 == device.getVendorId())) {
                        mUsbDescList.add(new UsbDevDesc(device.getVendorId(), device.getProductId()));
                    }
                }
            } else {
                ToastUtils.show("当前未找到USB设备");
                return;
            }
        }

        if(mUsbDescList.isEmpty()) {
            ToastUtils.show("未找到当前开发包支持的USB设备");
            return;
        }

        UsbDevDesc usbDev = null;
        for (Iterator<UsbDevDesc> it = mUsbDescList.iterator(); it.hasNext();) {
            usbDev = it.next();
            if (usbDev != null) {
                deviceFd = usbPermission.getUsbFileDescriptor(usbDev.usbVid, usbDev.usbPid);
                if (deviceFd < 0) {
                    deviceFd = usbPermission.getUsbFileDescriptor(usbDev.usbVid, usbDev.usbPid);
                    if (deviceFd < 0) {
                        String strShow = String.format("获取 USB[Vid:0x%02x,Pid:0x%02x]设备 描述符失败",usbDev.usbVid, usbDev.usbPid);
                        ToastUtils.show(strShow);
                        return;
                    }
                }
            } else {
                ToastUtils.show("未找到当前开发包支持的USB设备");
                return;
            }
        }

        st = Reader.iOpenUsbDevice(usbDev.usbVid, usbDev.usbPid,deviceFd, usbPermission.getUsbDevPath().getBytes());

        if (st > 0) {
            ToastUtils.show("打开USB端口成功");
        } else {
            ToastUtils.show("打开USB端口失败,st=" + st);
        }
    }

    public void deviceDisconnect(){
        long st = Reader.iCloseDevice();
        if (st == 0) {
            ToastUtils.show("关闭端口成功");
        } else {
            ToastUtils.show("关闭端口失败,ret=" + st);
        }
        clear();
    }

    private class UsbDevDesc{
        public int usbVid;
        public int usbPid;
        public UsbDevDesc(int vid,int pid){
            this.usbVid = vid;
            this.usbPid = pid;
        }
    }

    private void clear(){
        if (usbPermission != null){
            usbPermission.unUsbDevPermission();
            usbPermission = null;
        }
        if (mUsbDescList != null){
            mUsbDescList.clear();
            mUsbDescList = null;
        }
        context = null;
        readCallback = null;
        instance = null;
    }

    public void readIdCard() {
        int[] idcMsgLen = new int[2];
        byte[] idcMsg = new byte[4096];
        //不读指纹
        int  isReadFinger = 0;
        long ret = Reader.IDCardReadAll(idcMsgLen, idcMsg, isReadFinger);
        if(ret==0){

            HashMap<String, byte[]> FRIDCMsg = AnysizeIDCMsg.anysizeIDCMsg(isReadFinger,idcMsgLen[0],idcMsg);
            try {
                IdCardEntity idCardBean = new IdCardEntity();
                idCardBean.setName(new String(FRIDCMsg.get("ChinaName"),StandardCharsets.UTF_16LE).trim());
                idCardBean.setGender(new String(FRIDCMsg.get("Sex")).trim());
                idCardBean.setGroup(new String(FRIDCMsg.get("Nation")).trim());
                idCardBean.setBorn(new String(FRIDCMsg.get("Birth"), StandardCharsets.UTF_16LE).trim());
                idCardBean.setAddress(new String(FRIDCMsg.get("Address"),StandardCharsets.UTF_16LE).trim());
                idCardBean.setIdNumber(new String(FRIDCMsg.get("IDNum"),StandardCharsets.UTF_16LE).trim());
                idCardBean.setIssueAuthority(new String(FRIDCMsg.get("Issued"),StandardCharsets.UTF_16LE).trim());
                idCardBean.setStartDate(new String(FRIDCMsg.get("DateStart"),StandardCharsets.UTF_16LE).trim());
                idCardBean.setEndDate(new String(FRIDCMsg.get("DateEnd"),StandardCharsets.UTF_16LE).trim());

                if (IDCReaderSDK.GetLoadSoState()) {
                    //头像数据
                    byte[] wltData = AnysizeIDCMsg.CombinationWltData(idcMsgLen, idcMsg, isReadFinger);

                    ToolFun.initLicData(context, Environment.getExternalStorageDirectory() + "/wltlib");
                    int st = IDCReaderSDK.Init();
                    if(st == 0){
                        if(IDCReaderSDK.unpack(wltData,AnysizeIDCMsg.byLicData) == 1) {
                            String StrBmpFilePath = Environment.getExternalStorageDirectory() + "/wltlib/zp.bmp";
                            FileInputStream fis;
                            try {
                                fis = new FileInputStream(StrBmpFilePath);
                                idCardBean.setPhotoBitmap(BitmapFactory.decodeStream(fis));
                                fis.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                                if (readCallback != null){
                                    readCallback.errMsg(e.getMessage());
                                }
                            }

                            if (readCallback != null){
                                readCallback.idData(idCardBean);
                            }
                        } else {
                            if (readCallback != null){
                                readCallback.errMsg("身份证照片解码库解码失败");
                            }
                        }
                    }else{
                        if (readCallback != null){
                            readCallback.errMsg("身份证照片解码库初始化失败,st=" + st +",请检查< "+ Environment.getExternalStorageDirectory() + "/wltlib/ > 目录下是否有照片解码库授权文件!");
                        }
                    }
                }else {
                    if (readCallback != null){
                        readCallback.errMsg("未找到身份证照片解码库libwltdecode.so!");
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                if (readCallback != null){ readCallback.errMsg(e.getMessage()); }
            }
        }else{
            if (readCallback != null){
                if (ret == -12){
                    if (readCallback != null){
                        readCallback.errMsg(READ_ERR_NO_CONNECT);
                    }
                }else if (ret == -50){
                    if (readCallback != null){
                        readCallback.errMsg(READ_ERR_CARD_NULL);
                    }
                }else {
                    if (readCallback != null){
                        readCallback.errMsg("获取身份证信息失败! ret:"+ret);
                    }
                }
            }
        }
    }

    public void readSocial() {
        byte[] pOutInfo = new byte[4096];
        long ret = Reader.iReadCardBas(iType, pOutInfo);
        String strCardInfo = new String(pOutInfo).trim();
        if (ret != 0) {
            if (ret == -206){
                if (readCallback != null){
                    if (readCallback != null){
                        readCallback.errMsg(READ_ERR_PSAM_NULL);
                    }
                }
            }else {
                LogUtils.INSTANCE.d("__readSocial-e1",strCardInfo + " ret = "+ret);
                if (ret != -2){
                    LogUtils.INSTANCE.dw("__readSocial-e",strCardInfo + " ret = "+ret);
                }
                if (readCallback != null){
                    readCallback.errMsg(strCardInfo);
                }
            }
            return;
        }
        try {
            String[] strCardMsg = strCardInfo.split("\\|");
            SocialCardEntity socialCardEntity = new SocialCardEntity();
            socialCardEntity.setAdminCode(strCardMsg[0]);
            socialCardEntity.setIdCardNum(strCardMsg[1]);

            if (Integer.parseInt(strCardMsg[1].substring(17,18)) % 2 == 0){
                socialCardEntity.setGender("女");
            }else {
                socialCardEntity.setGender("男");
            }
            socialCardEntity.setCardNum(strCardMsg[2]);
            socialCardEntity.setCardId(strCardMsg[3]);
            socialCardEntity.setName(strCardMsg[4]);
            socialCardEntity.setResetCode(strCardMsg[5]);
            socialCardEntity.setVersion(strCardMsg[6]);
            socialCardEntity.setStartDate(strCardMsg[7]);
            socialCardEntity.setEndDate(strCardMsg[8]);
            socialCardEntity.setTerminalCode(strCardMsg[9]);
            socialCardEntity.setTerminalDeviceCode(strCardMsg[10]);
            if (readCallback != null){
                readCallback.socialData(socialCardEntity);
            }
        } catch (Exception e){
            if (readCallback != null){
                readCallback.errMsg(e.getMessage());
            }
        }
    }

}
